package com.zlc.workflow.core.process.cmd;

import com.zlc.common.core.process.model.vo.*;
import com.zlc.common.core.process.service.*;
import com.zlc.common.util.AssertUtils;
import com.zlc.common.util.BeanCopyUtils;
import com.zlc.workflow.constant.AuthResEnum;
import com.zlc.workflow.core.process.model.*;
import com.zlc.workflow.core.process.model.design.AntDesignEntity;
import com.zlc.workflow.core.process.model.design.AntDesignUtil;
import com.zlc.workflow.flow.NodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class QueryProcessCmd {

    @Autowired
    private StoneProcessService stoneProcessService;
    @Autowired
    private StoneProcessNodeService stoneProcessNodeService;
    @Autowired
    private StoneNodeApproveConfigService stoneNodeApproveConfigService;
    @Autowired
    private StoneNodeApproveUserConfigService stoneNodeApproveUserConfigService;
    @Autowired
    private StoneProcessAuthConfigService stoneProcessAuthConfigService;
    @Autowired
    private StoneEventConfigService stoneEventConfigService;
    @Autowired
    private StoneProcessVariableConfigService stoneProcessVariableConfigService;
    @Autowired
    private StoneProcessFormConfigService stoneProcessFormConfigService;

    public ProcessDeployEntity query(String processId) {
        ProcessDeployEntity result = new ProcessDeployEntity();
        //流程定义信息
        StoneProcessVo processVo = stoneProcessService.getByProcessId(processId);
        byte[] content = processVo.getContent();
        result.setContent(NodeUtils.getProcessContent(content));
        //流程json对象
        FlowProcess process = new ParseXmlToJsonCmd(result.getContent()).execute();
        result.setProcess(process);
        //ant
        AntDesignEntity entity = AntDesignUtil.buildAntDesignEntity(process, processId);
        result.setDesign(entity);
        AssertUtils.isTrue(!ObjectUtils.isEmpty(processVo), "流程" + processId + "不存在");
        result.setProcessId(processVo.getProcessId());
        result.setClassId(processVo.getClassId());
        processVo.setContent(null);
        result.setProcessVo(processVo);

        //审批配置
        List<StoneNodeApproveConfigVo> approveConfigVos = stoneNodeApproveConfigService.getByProcessId(processId);
        //审批人配置
        List<StoneNodeApproveUserConfigVo> userConfigVos = stoneNodeApproveUserConfigService.getByProcessId(processId);
        //事件配置
        List<StoneEventConfigVo> eventConfigVos = stoneEventConfigService.getByProcessId(processId);
        //权限配置
        List<StoneProcessAuthConfigVo> authConfigVos = stoneProcessAuthConfigService.getByProcessId(processId);
        //表单配置
        List<StoneProcessFormConfigVo> formConfigVos = stoneProcessFormConfigService.getByProcessId(processId);

        //流程事件配置
        List<StoneEventConfigVo> processEvents = stoneEventConfigService.getProcessEvents(processId);
        if (!ObjectUtils.isEmpty(processEvents)) {
            List<ProcessEventConfig> eventConfigs = BeanCopyUtils.copyObjList(processEvents, ProcessEventConfig.class);
            for(ProcessEventConfig eventConfig : eventConfigs){
                List<StoneNodeApproveUserConfigVo> eventUserConfigs = userConfigVos.stream()
                        .filter(u -> eventConfig.getEventId() != null && eventConfig.getEventId().equals(u.getEventId()))
                        .sorted(Comparator.comparing(StoneNodeApproveUserConfigVo::getOrder)).collect(Collectors.toList());
                if(!ObjectUtils.isEmpty(eventUserConfigs)){
                    List<NodeApproveUserConfig> copyUsers = BeanCopyUtils.copyObjList(eventUserConfigs, NodeApproveUserConfig.class);
                    eventConfig.setUserConfigList(copyUsers);
                }
            }
            result.setEventConfigs(eventConfigs);
        }
        //流程权限配置
        List<StoneProcessAuthConfigVo> processAuth = stoneProcessAuthConfigService.getProcessAuth(processId);
        if (!ObjectUtils.isEmpty(processAuth)) {
            List<NodeAuthConfig> authConfigs = BeanCopyUtils.copyObjList(processAuth, NodeAuthConfig.class);
            result.setAuthConfigs(authConfigs);
        }
        //流程变量配置
        List<StoneProcessVariableConfigVo> variableConfigVos = stoneProcessVariableConfigService.getProcessVariables(processId);
        if (!ObjectUtils.isEmpty(variableConfigVos)) {
            List<StoneProcessVariableConfigVo> processVariableConfigVos = variableConfigVos.stream().filter(v -> ObjectUtils.isEmpty(v.getNodeId())).collect(Collectors.toList());
            List<ProcessVariableConfig> variableConfigs = BeanCopyUtils.copyObjList(processVariableConfigVos, ProcessVariableConfig.class);
            result.setVariableConfigs(variableConfigs);
        }
        //节点配置
        List<StoneProcessNodeVo> nodeVos = stoneProcessNodeService.getByProcessId(processId);
        if (!ObjectUtils.isEmpty(nodeVos)) {
            List<ProcessNodeEntity> nodeEntities = BeanCopyUtils.copyObjList(nodeVos, ProcessNodeEntity.class);

            for (ProcessNodeEntity nodeEntity : nodeEntities) {
                String nodeId = nodeEntity.getNodeId();
                //审批配置
                StoneNodeApproveConfigVo approveConfigVo = approveConfigVos.stream().filter(a -> nodeId.equals(a.getNodeId())).findFirst().orElse(null);
                if (!ObjectUtils.isEmpty(approveConfigVo)) {
                    NodeApproveConfig approveConfig = BeanCopyUtils.copyObj(approveConfigVo, NodeApproveConfig.class);
                    //审批人配置
                    List<StoneNodeApproveUserConfigVo> nodeUserConfigTrueVos = userConfigVos.stream().filter(u -> approveConfig.getConfigId().equals(u.getConfigId())
                              && "TRUE".equals(u.getConditionRes()))
                            .sorted(Comparator.comparing(StoneNodeApproveUserConfigVo::getOrder)).collect(Collectors.toList());
                    List<StoneNodeApproveUserConfigVo> nodeUserConfigFalseVos = userConfigVos.stream().filter(u -> approveConfig.getConfigId().equals(u.getConfigId())
                                    && "FALSE".equals(u.getConditionRes()))
                            .sorted(Comparator.comparing(StoneNodeApproveUserConfigVo::getOrder)).collect(Collectors.toList());
                    List<StoneNodeApproveUserConfigVo> nodeUserConfigVos = userConfigVos.stream().filter(u -> approveConfig.getConfigId().equals(u.getConfigId())
                                    && "NO".equals(u.getConditionRes()))
                            .sorted(Comparator.comparing(StoneNodeApproveUserConfigVo::getOrder)).collect(Collectors.toList());
                    if (!ObjectUtils.isEmpty(nodeUserConfigVos)) {
                        List<NodeApproveUserConfig> userConfigList = BeanCopyUtils.copyObjList(nodeUserConfigVos, NodeApproveUserConfig.class);
                        approveConfig.setUserConfigList(userConfigList);
                    }
                    if (!ObjectUtils.isEmpty(nodeUserConfigTrueVos)) {
                        List<NodeApproveUserConfig> userConfigList = BeanCopyUtils.copyObjList(nodeUserConfigTrueVos, NodeApproveUserConfig.class);
                        approveConfig.setConditionTrueUserConfigList(userConfigList);
                    }
                    if (!ObjectUtils.isEmpty(nodeUserConfigFalseVos)) {
                        List<NodeApproveUserConfig> userConfigList = BeanCopyUtils.copyObjList(nodeUserConfigFalseVos, NodeApproveUserConfig.class);
                        approveConfig.setConditionFalseUserConfigList(userConfigList);
                    }
                    nodeEntity.setApproveConfig(approveConfig);
                }
                //事件配置
                List<StoneEventConfigVo> eventConfigList = eventConfigVos.stream().filter(e -> nodeId.equals(e.getNodeId()))
                        .sorted(Comparator.comparing(StoneEventConfigVo::getOrder)).collect(Collectors.toList());
                if (!ObjectUtils.isEmpty(eventConfigList)) {
                    List<ProcessEventConfig> eventConfigs = BeanCopyUtils.copyObjList(eventConfigList, ProcessEventConfig.class);
                    for(ProcessEventConfig eventConfig : eventConfigs){
                        List<StoneNodeApproveUserConfigVo> eventUserConfigs = userConfigVos.stream()
                                .filter(u -> eventConfig.getEventId() != null && eventConfig.getEventId().equals(u.getEventId()))
                                .sorted(Comparator.comparing(StoneNodeApproveUserConfigVo::getOrder)).collect(Collectors.toList());
                        if(!ObjectUtils.isEmpty(eventUserConfigs)){
                            List<NodeApproveUserConfig> copyUsers = BeanCopyUtils.copyObjList(eventUserConfigs, NodeApproveUserConfig.class);
                            eventConfig.setUserConfigList(copyUsers);
                        }
                    }
                    nodeEntity.setEventConfigs(eventConfigs);
                }
                //权限配置
                List<StoneProcessAuthConfigVo> nodeAuthConfigs = authConfigVos.stream().filter(a -> nodeId.equals(a.getNodeId()))
                        .sorted(((o1, o2) -> AuthResEnum.getOrder(o1.getAuthRes()) > AuthResEnum.getOrder(o2.getAuthRes()) ? 0 : 1))
                        .collect(Collectors.toList());
                if (!ObjectUtils.isEmpty(nodeAuthConfigs)) {
                    List<NodeAuthConfig> authConfigs = BeanCopyUtils.copyObjList(nodeAuthConfigs, NodeAuthConfig.class);
                    nodeEntity.setAuthConfigs(authConfigs);
                }
                //变量配置
                List<StoneProcessVariableConfigVo> nodeVariableVos = variableConfigVos.stream().filter(v -> nodeId.equals(v.getNodeId()))
                        .sorted(Comparator.comparing(StoneProcessVariableConfigVo::getOrder))
                        .collect(Collectors.toList());
                if (!ObjectUtils.isEmpty(nodeVariableVos)) {
                    List<ProcessVariableConfig> variableConfigs = BeanCopyUtils.copyObjList(nodeVariableVos, ProcessVariableConfig.class);
                    nodeEntity.setVariableConfigs(variableConfigs);
                }
                //表单配置
                List<StoneProcessFormConfigVo> nodeFormConfigVos = formConfigVos.stream().filter(f -> nodeId.equals(f.getNodeId()))
                        .sorted(Comparator.comparing(StoneProcessFormConfigVo::getOrder))
                        .collect(Collectors.toList());
                if (!ObjectUtils.isEmpty(nodeFormConfigVos)) {
                    List<ProcessFormConfig> formConfigs = BeanCopyUtils.copyObjList(nodeFormConfigVos, ProcessFormConfig.class);
                    nodeEntity.setFormConfigs(formConfigs);
                }
            }
            result.setNodeEntities(nodeEntities);
        }
        return result;
    }


}
